package com.bytecodezz.jc.composetesting

import androidx.compose.material3.Text
import androidx.compose.ui.test.*
import androidx.compose.ui.test.junit4.createComposeRule
import com.bytecodezz.jc.composetesting.ui.components.RallyTopAppBar
import org.junit.Rule
import org.junit.Test

// 注意需要将主app的后台弹窗权限打开
class TopAppBarTest {

    @get:Rule
    val composeTestRule = createComposeRule()

    @Test
    fun myTest() {
        composeTestRule.setContent {
            Text(text = "You can set any Compose content")
        }
    }

    // 起始测试
    @Test
    fun topAppBarTest() {
        val allScreens = RallyScreen.values().toList()
        composeTestRule.setContent {
            RallyTopAppBar(
                allScreens = allScreens,
                onTabSelected = { },
                currentScreen = RallyScreen.Overview
            )
        }
        composeTestRule
            .onNodeWithContentDescription(label = RallyScreen.Overview.name)
            .assertIsSelected()
    }

    @Test // 测试Label标签是否存在UI界面中
    fun rallyTopAppBarTest_currentLabelExists() {
        val allScreens = RallyScreen.values().toList()
        // 构建局部组件
        composeTestRule.setContent {
            RallyTopAppBar(
                allScreens = allScreens,
                onTabSelected = { },
                currentScreen = RallyScreen.Overview
            )
        }
        // 对构建的组件进行测试
        // onNodeWithText查找语义树中是否存在文本内容，并断言
        // 结果断言失败  后面语义树打印信息知道，该UI中不存在名字
//        composeTestRule
//            .onNodeWithText(RallyScreen.Accounts.name.uppercase())
//            .assertExists()

        // 打印语义树的所有属性   所有查找基本都是从该语义树中而来  useUnmergedTree 打印未合并的子节点
        composeTestRule.onRoot(useUnmergedTree = true)
            .printToLog(tag = "currentLabelExists") // 打印当前Label中的

        composeTestRule
            .onNodeWithContentDescription(label = RallyScreen.Accounts.name)
            .assertExists()
        // 该测试无意义，因为打印的语义树中可以看到，即使未选中 上面的三个top bar的信息都在语义树中

        // 根据 打印属性 useUnmergedTree = true 开启了子节点展开 知道当前选中项是未合并子节点的，断言查找该子节点
        // 遍历节点
        composeTestRule
            .onNode(
                useUnmergedTree = true,
                matcher = hasText(RallyScreen.Overview.name.uppercase()) and hasParent(
                    hasContentDescription(RallyScreen.Overview.name)
                )
            )
            .assertExists()

    }

    @Test
    fun topAppBarClicksTest() {
        composeTestRule.setContent {
            RallyApp()
        }
        composeTestRule
            .onRoot(useUnmergedTree = true)
            .printToLog("AppTestNode")
        for (i in 1..5) {
            foreachTest()
        }
    }

    private fun foreachTest() {
        // 点击第一个bar
        composeTestRule
            .onNodeWithContentDescription(label = RallyScreen.Overview.name)
            .performClick()
        // 断言第一个bar是否被选中
        composeTestRule
            .onNodeWithContentDescription(label = RallyScreen.Overview.name)
            .assertIsSelected()
        // 断言第一个bar的文字是否展开显示
        composeTestRule.onNode(
            useUnmergedTree = true,
            matcher = hasText(RallyScreen.Overview.name.uppercase()) and hasParent(
                matcher = hasContentDescription(RallyScreen.Overview.name)
            )
        ).assertExists()

        Thread.sleep(1000)
        // 点击第二个bar
        composeTestRule
            .onNodeWithContentDescription(label = RallyScreen.Accounts.name)
            .performClick()
        // 断言第二个bar是否被选中
        composeTestRule
            .onNodeWithContentDescription(label = RallyScreen.Accounts.name)
            .assertIsSelected()
        // 断言第二个bar的文字是否展开显示
        composeTestRule.onNode(
            useUnmergedTree = true,
            matcher = hasText(RallyScreen.Accounts.name.uppercase()) and hasParent(
                matcher = hasContentDescription(RallyScreen.Accounts.name)
            )
        ).assertExists()

        Thread.sleep(1000)
        // 点击第三个bar
        composeTestRule
            .onNodeWithContentDescription(label = RallyScreen.Bills.name)
            .performClick()
        // 断言第三个bar是否被选中
        composeTestRule
            .onNodeWithContentDescription(label = RallyScreen.Bills.name)
            .assertIsSelected()
        // 断言第三个bar的文字是否展开显示
        composeTestRule.onNode(
            useUnmergedTree = true,
            matcher = hasText(RallyScreen.Bills.name.uppercase()) and hasParent(
                matcher = hasContentDescription(RallyScreen.Bills.name)
            )
        ).assertExists()

        Thread.sleep(3000)
    }


}